package com.linciping.useges.plugin.action;

import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.linciping.useges.plugin.bean.File2R;
import com.linciping.useges.plugin.util.ProjectFileUtil;
import com.linciping.useges.plugin.util.XmlResSaxHandler;
import org.jetbrains.jps.model.java.JavaResourceRootType;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import org.jetbrains.kotlin.config.ResourceKotlinRootType;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public abstract class ResUsegesAction extends BaseUsegesAction {

    private static final Logger LOGGER = Logger.getInstance(ResUsegesAction.class);
    private static final String LAYOUT = "layout";
    private static final String DRAWABLE = "drawable";
    private static final String MIPMAP = "mipmap";
    private static final String ANIM = "anim";

    private List<File2R> layoutConstantList;
    private final List<File2R> drawableConstantList = new ArrayList<>();
    private final List<File2R> mipmapConstantList = new ArrayList<>();
    private List<File2R> animConstantList;

    private final List<File2R> stringConstantList = new ArrayList<>();
    private final List<File2R> attrConstantList = new ArrayList<>();
    private final List<File2R> boolConstantList = new ArrayList<>();
    private final List<File2R> colorConstantList = new ArrayList<>();
    private final List<File2R> dimeConstantList = new ArrayList<>();
    private final List<File2R> integerConstantList = new ArrayList<>();
    private final List<File2R> styleConstantList = new ArrayList<>();
    private final List<File2R> idsConstantList = new ArrayList<>();
    private final List<File2R> arrayConstantList = new ArrayList<>();
    private XmlResSaxHandler xmlResSaxHandler;

    private final List<File2R> resRList = new ArrayList<>();

    @Override
    public void actionPerformed(AnActionEvent e) {
        dataReset();
        Project project = e.getProject();
        xmlResSaxHandler = new XmlResSaxHandler();
        Module targetModule = e.getData(LangDataKeys.MODULE);
        List<VirtualFile> virtualFileList = ProjectFileUtil.getModuleResourceList(targetModule, false, true);
        for (VirtualFile resRoot : virtualFileList) {
            PsiDirectory rootDirectory = PsiManager.getInstance(project).findDirectory(resRoot);
            PsiDirectory[] rootChildrenList = rootDirectory.getSubdirectories();
            for (PsiDirectory rootChildren : rootChildrenList) {
                String name = rootChildren.getName();
                PsiFile[] psiFiles = rootChildren.getFiles();
                if (name.equals(LAYOUT)) {
                    String constantPrefix = "R.layout.";
                    layoutConstantList = new ArrayList<>(psiFiles.length);
                    for (PsiFile layout : psiFiles) {
                        String resName = getFileName(layout);
                        String constantR = constantPrefix + resName;
                        File2R file2R = new File2R(layout, resName, constantR);
                        layoutConstantList.add(file2R);
                    }
                } else if (name.equals(ANIM)) {
                    String constantPrefix = "R.anim.";
                    animConstantList = new ArrayList<>(psiFiles.length);
                    for (PsiFile anim : psiFiles) {
                        String resName = getFileName(anim);
                        String constantR = constantPrefix + resName;
                        File2R file2R = new File2R(anim, resName, constantR);
                        animConstantList.add(file2R);
                    }
                } else if (name.contains(DRAWABLE)) {
                    String constantPrefix = "R.drawable.";
                    for (PsiFile drawable : psiFiles) {
                        String resName = getFileName(drawable);
                        String drawableName = constantPrefix + resName;
                        File2R file2R = new File2R(drawable, resName, drawableName);
                        if (!drawableConstantList.contains(file2R)) {
                            drawableConstantList.add(file2R);
                        }
                    }
                } else if (name.contains(MIPMAP)) {
                    String constantPrefix = "R.mipmap.";
                    for (PsiFile mipmap : psiFiles) {
                        String resName = getFileName(mipmap);
                        String mipmapName = constantPrefix + resName;
                        File2R file2R = new File2R(mipmap, resName, mipmapName);
                        if (!mipmapConstantList.contains(file2R)) {
                            mipmapConstantList.add(file2R);
                        }
                    }
                } else {
                    for (PsiFile psiFile : psiFiles) {
                        if (isXmlFile(psiFile)) {
                            parseXml(psiFile);
                        }
                    }
                }
            }
        }
        if (layoutConstantList != null) {
            resRList.addAll(layoutConstantList);
        }
        resRList.addAll(drawableConstantList);
        if (animConstantList != null) {
            resRList.addAll(animConstantList);
        }
        resRList.addAll(stringConstantList);
        resRList.addAll(attrConstantList);
        resRList.addAll(boolConstantList);
        resRList.addAll(colorConstantList);
        resRList.addAll(dimeConstantList);
        resRList.addAll(integerConstantList);
        resRList.addAll(styleConstantList);
        resRList.addAll(idsConstantList);
        resRList.addAll(arrayConstantList);
        find(project, resRList, targetModule);
    }


    protected abstract void find(Project project, List<File2R> resRList, Module targetModule);

    protected boolean isBuildSource(String path) {
        return path.contains("build");
    }

    private void dataReset() {
        if (layoutConstantList != null) {
            layoutConstantList.clear();
        }
        if (animConstantList != null) {
            animConstantList.clear();
        }
        drawableConstantList.clear();
        stringConstantList.clear();
        attrConstantList.clear();
        boolConstantList.clear();
        colorConstantList.clear();
        dimeConstantList.clear();
        integerConstantList.clear();
        styleConstantList.clear();
        idsConstantList.clear();
        arrayConstantList.clear();
        resRList.clear();
    }

    private void parseXml(PsiFile psiFile) {
        String xmlContent = psiFile.getText();
        try {
            xmlResSaxHandler.createViewList(psiFile, xmlContent);
            stringConstantList.addAll(xmlResSaxHandler.getStringConstantList());
            attrConstantList.addAll(xmlResSaxHandler.getAttrConstantList());
            boolConstantList.addAll(xmlResSaxHandler.getBoolConstantList());
            colorConstantList.addAll(xmlResSaxHandler.getColorConstantList());
            dimeConstantList.addAll(xmlResSaxHandler.getDimeConstantList());
            integerConstantList.addAll(xmlResSaxHandler.getIntegerConstantList());
            styleConstantList.addAll(xmlResSaxHandler.getStyleConstantList());
            idsConstantList.addAll(xmlResSaxHandler.getIdsConstantList());
            arrayConstantList.addAll(xmlResSaxHandler.getArrayConstantList());
        } catch (Exception exception) {
            LOGGER.error(exception.getMessage());
        }
    }

    private boolean isXmlFile(PsiFile psiFile) {
        return psiFile.getName().endsWith(".xml");
    }

    private String getFileName(PsiFile psiFile) {
        String fileName = psiFile.getName();
        String regex = ".";
        String[] fileNameSplits = fileName.split("\\.");
        if (fileNameSplits.length == 1) {
            return fileName;
        } else {
            String fileType = regex + fileNameSplits[fileNameSplits.length - 1];
            return fileName.replace(fileType, "");
        }
    }

}
